<?php
namespace config\lib;

use config\lib\Route;

class App
{
    //是否初始化
    protected static $init = false;
    //默认命名空间
    public static $namespace = 'app';
    //调度信息
    protected static $dispatch = [];

    /**
     * 运行控制器和方法
     * @throws \Exception
     */
    public static function run(Request $request = null)
    {
        //创建request 代理请求
        $request = is_null($request) ? Request::instance() : $request;

        //确定日志存储方式
        Log::init();

        //请求路径解析
        $route = new Route();
        $prat_url = [MODULE,$route->ctrl,$route->action];

        //绑定调度信息
        $dispatch = self::$dispatch;
        if(empty($dispatch)){
            $dispatch = self::dispatch($prat_url);
        }

        //执行请求
        $data = self::exec($dispatch);

        //输出数据到客户端
        if(!is_null($data)){
            $type = 'html';
            $response = Response::create($data,$type);
        }else{
            $response = Response::create();
        }

        //写日志
        Log::log('ctrl:'.$route->ctrl.'  '.'action:'.$route->action);
        return $response;
    }

    //设置调度信息
    public static function dispatch($dispatch, $type = 'module')
    {
        return self::$dispatch = ['type'=>$type,$type=>$dispatch];
    }

    //调度分发
    public static function exec($dispatch)
    {
        switch ($dispatch['type']){
            case 'module':
                $data = self::module($dispatch['module']);
                break;
            default:
                $data = null;
                break;
        }
        return $data;
    }

    //执行模块
    public static function module($result)
    {
        $request = Request::instance();

        $moduleName = $result[0];
        $controllerName = $result[1];
        $actionName = $result[2];

        //设置当前请求操作 & 操作
        $request->module($moduleName)->controller($controllerName)->action($actionName);

        //实例化控制器
        $instance = Loader::controller($controllerName);

        $call = [$instance,$actionName];

        return self::invokeMethod($call);
    }

    //反射执行类
    public static function invokeMethod($method)
    {
        if(is_array($method)){
            $class   = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]);
            //判断方法是否存在
            if(!method_exists($class,$method[1])){
                echo 'action not exists:'.$method[1];exit;
            }
            $reflect = new \ReflectionMethod($class, $method[1]);
        }else{
            //静态方法
            $reflect = new \ReflectionMethod($method);
        }

        return $reflect->invokeArgs(isset($class) ? $class : null,[]);
    }

    //反射实例化类
    public static function invokeClass($class,$var = [])
    {
        $reflect     = new \ReflectionClass($class);
        $constructor = $reflect->getConstructor();

        return $reflect->newInstance();
    }
}
